from rest_framework import generics, status, permissions
from rest_framework.decorators import api_view, permission_classes
from rest_framework.response import Response
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import OrderingFilter
from django.db.models import Sum, Count, Avg, F
from django.utils import timezone
from datetime import timedelta
from .models import (
    StockAlert, StockMovement, Supplier,
    PurchaseOrder, PurchaseOrderItem, GlobalStockSettings
)
from .serializers import (
    StockAlertSerializer, StockMovementSerializer,
    StockMovementCreateSerializer, SupplierSerializer,
    PurchaseOrderListSerializer, PurchaseOrderDetailSerializer,
    PurchaseOrderCreateSerializer, GlobalStockSettingsSerializer,
    StockReportSerializer, SupplierReportSerializer
)
from .filters import (
    StockAlertFilter, StockMovementFilter, 
    SupplierFilter, PurchaseOrderFilter
)


class GlobalStockSettingsView(generics.RetrieveUpdateAPIView):
    queryset = GlobalStockSettings.objects.all()
    serializer_class = GlobalStockSettingsSerializer
    permission_classes = [permissions.IsAdminUser]
    
    def get_object(self):
        return GlobalStockSettings.objects.first() or GlobalStockSettings.objects.create()


class StockAlertListView(generics.ListAPIView):
    queryset = StockAlert.objects.all()
    serializer_class = StockAlertSerializer
    permission_classes = [permissions.IsAdminUser]
    filter_backends = [DjangoFilterBackend, OrderingFilter]
    filterset_class = StockAlertFilter
    ordering_fields = ['created_at', 'current_stock', 'threshold']
    ordering = ['-created_at']


class StockAlertResolveView(generics.UpdateAPIView):
    queryset = StockAlert.objects.all()
    serializer_class = StockAlertSerializer
    permission_classes = [permissions.IsAdminUser]
    
    def patch(self, request, *args, **kwargs):
        alert = self.get_object()
        alert.is_resolved = True
        alert.save()
        
        return Response({
            'message': '库存预警已解决',
            'alert': StockAlertSerializer(alert).data
        })


class StockMovementListView(generics.ListAPIView):
    queryset = StockMovement.objects.all()
    serializer_class = StockMovementSerializer
    permission_classes = [permissions.IsAdminUser]
    filter_backends = [DjangoFilterBackend, OrderingFilter]
    filterset_class = StockMovementFilter
    ordering_fields = ['created_at', 'quantity']
    ordering = ['-created_at']


class StockMovementCreateView(generics.CreateAPIView):
    queryset = StockMovement.objects.all()
    serializer_class = StockMovementCreateSerializer
    permission_classes = [permissions.IsAdminUser]
    
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        
        movement = serializer.save()
        
        # 更新图书库存
        book = movement.book
        book.stock_quantity = movement.new_quantity
        book.save()
        
        return Response(
            StockMovementSerializer(movement).data,
            status=status.HTTP_201_CREATED
        )


class SupplierListView(generics.ListCreateAPIView):
    queryset = Supplier.objects.all()
    serializer_class = SupplierSerializer
    permission_classes = [permissions.IsAdminUser]
    filter_backends = [DjangoFilterBackend, OrderingFilter]
    filterset_class = SupplierFilter
    ordering_fields = ['name', 'created_at']
    ordering = ['name']


class SupplierDetailView(generics.RetrieveUpdateDestroyAPIView):
    queryset = Supplier.objects.all()
    serializer_class = SupplierSerializer
    permission_classes = [permissions.IsAdminUser]


class PurchaseOrderListView(generics.ListCreateAPIView):
    queryset = PurchaseOrder.objects.all()
    serializer_class = PurchaseOrderListSerializer
    permission_classes = [permissions.IsAdminUser]
    filter_backends = [DjangoFilterBackend, OrderingFilter]
    filterset_class = PurchaseOrderFilter
    ordering_fields = ['order_date', 'expected_date', 'total_amount']
    ordering = ['-order_date']


class PurchaseOrderDetailView(generics.RetrieveUpdateAPIView):
    queryset = PurchaseOrder.objects.all()
    serializer_class = PurchaseOrderDetailSerializer
    permission_classes = [permissions.IsAdminUser]


class PurchaseOrderCreateView(generics.CreateAPIView):
    queryset = PurchaseOrder.objects.all()
    serializer_class = PurchaseOrderCreateSerializer
    permission_classes = [permissions.IsAdminUser]


class PurchaseOrderReceiveView(generics.UpdateAPIView):
    queryset = PurchaseOrder.objects.all()
    serializer_class = PurchaseOrderDetailSerializer
    permission_classes = [permissions.IsAdminUser]
    
    def patch(self, request, *args, **kwargs):
        purchase_order = self.get_object()
        
        if purchase_order.status != 'pending':
            return Response(
                {'error': '采购订单状态无法接收'},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        purchase_order.status = 'received'
        purchase_order.received_date = timezone.now()
        purchase_order.save()
        
        # 更新库存
        for item in purchase_order.items.all():
            book = item.book
            book.stock_quantity += item.quantity
            book.save()
            
            # 记录库存变动
            StockMovement.objects.create(
                book=book,
                movement_type='in',
                quantity=item.quantity,
                previous_quantity=book.stock_quantity - item.quantity,
                new_quantity=book.stock_quantity,
                reference_number=purchase_order.order_number,
                note=f"采购订单 {purchase_order.order_number} 入库"
            )
        
        return Response({
            'message': '采购订单已接收，库存已更新',
            'purchase_order': PurchaseOrderDetailSerializer(purchase_order).data
        })


@api_view(['GET'])
@permission_classes([permissions.IsAdminUser])
def stock_report(request):
    from books.models import Book
    
    # 库存统计
    total_books = Book.objects.count()
    low_stock_books = Book.objects.filter(
        stock_quantity__lte=F('min_stock_alert')
    ).count()
    out_of_stock_books = Book.objects.filter(stock_quantity=0).count()
    
    # 计算库存总价值
    total_value = Book.objects.aggregate(
        total=Sum(F('stock_quantity') * F('price'))
    )['total'] or 0
    
    report = StockReportSerializer({
        'total_books': total_books,
        'low_stock_books': low_stock_books,
        'out_of_stock_books': out_of_stock_books,
        'total_value': total_value
    }).data
    
    return Response(report)


@api_view(['GET'])
@permission_classes([permissions.IsAdminUser])
def supplier_report(request):
    from django.db.models import Sum, Count
    
    suppliers = Supplier.objects.annotate(
        total_orders=Count('purchase_orders'),
        total_amount=Sum('purchase_orders__total_amount'),
        average_order_amount=Avg('purchase_orders__total_amount')
    ).filter(total_orders__gt=0)
    
    report_data = []
    for supplier in suppliers:
        report_data.append({
            'supplier_name': supplier.name,
            'total_orders': supplier.total_orders,
            'total_amount': supplier.total_amount or 0,
            'average_order_amount': supplier.average_order_amount or 0
        })
    
    return Response(report_data)


@api_view(['GET'])
@permission_classes([permissions.IsAdminUser])
def low_stock_alerts(request):
    from books.models import Book
    
    low_stock_books = Book.objects.filter(
        stock_quantity__lte=F('min_stock_alert')
    ).values(
        'id', 'title', 'isbn', 'stock_quantity', 'min_stock_alert'
    )
    
    return Response(list(low_stock_books))


@api_view(['POST'])
@permission_classes([permissions.IsAdminUser])
def generate_stock_alerts(request):
    from books.models import Book
    
    alerts_created = 0
    
    # 获取全局设置
    settings = GlobalStockSettings.objects.first()
    if not settings:
        settings = GlobalStockSettings.objects.create()
    
    # 检查每本书的库存
    for book in Book.objects.all():
        if book.stock_quantity <= book.min_stock_alert:
            alert, created = StockAlert.objects.get_or_create(
                book=book,
                alert_type='low_stock',
                defaults={
                    'current_stock': book.stock_quantity,
                    'threshold': book.min_stock_alert
                }
            )
            if created:
                alerts_created += 1
    
    return Response({
        'message': f'已生成 {alerts_created} 个库存预警',
        'alerts_created': alerts_created
    })
